package com.track.utils;

import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 脚本执行器
 *
 * @author Administrator
 */
@Slf4j
@UtilityClass
public class ShellExecutor {

    @SneakyThrows
    public String exec(String[] commands) {
        StringBuilder builder = new StringBuilder();
        BufferedReader bufferIn = null;
        BufferedReader bufferError = null;
        Process process = null;
        try {
            for (String cmd : commands) {
                // 子进程执行 shell
                process = Runtime.getRuntime().exec(new String[] { "/bin/bash", "-c", cmd });
                int exitValue = process.waitFor();

                if (exitValue != 0) {
                    log.debug("Call shell failed. error code is {}", exitValue);
                }

                // 获取命令执行结果, 有两个结果: 正常的输出 和 错误的输出（PS: 子进程的输出就是主进程的输入）
                bufferIn = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
                bufferError = new BufferedReader(new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8));

                // 读取输出
                String line;
                while ((line = bufferIn.readLine()) != null) {
                    builder.append(line).append('\n');
                }
                while ((line = bufferError.readLine()) != null) {
                    builder.append(line).append('\n');
                }
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            IOUtils.close(bufferIn);
            IOUtils.close(bufferError);

            // 销毁子进程
            if (Objects.nonNull(process)) {
                process.destroy();
            }
        }
        return builder.toString();
    }

    public String exec(String command) {
        return exec(new String[]{ command });
    }

}
